#include <stdio.h>
#include "xdisk.h"
#include "xfat.h"

/*
 * vdisk_open
 * virture disk open
 * 
 * */
xfat_err_t vdisk_open(struct _xdisk_t *disk, void *init_data)
{
    const char *path = init_data;
    FILE  *file = fopen(path, "rb+");
    if(file == NULL)
    {
        printf("open vdisk failed <%s>\r\n", path);
        return FS_ERR_EIO;
    }

    disk->data = file;
    disk->sector_size = 512;

    fseek(file, 0, SEEK_END);
    disk->total_sector =  ftell(file) / disk->sector_size;

    return FS_ERR_EOK;
}


/*
 * vdisk_read
 * virture disk read sector
 * from start sector
 * 
 * */
xfat_err_t vdisk_read(struct _xdisk_t *disk, u8_t *buffer, u32_t start_sector, u32_t count)
{
    u32_t offset = start_sector * disk->sector_size;
    FILE *file = (FILE *)disk->data;
    
    int  err = fseek(file, offset, SEEK_SET);
    if (err == -1)
    {
        printf("vdisk read seek_set error: 0x%x\r\n", offset);
        return FS_ERR_EIO;
    }

    err = fread(buffer, disk->sector_size, count, file);
    if (err == -1)
    {
        printf("vdisk read file read error\r\n");
        return FS_ERR_EIO;
    }
    
    return FS_ERR_EOK;
}


/*
 * vdisk_write
 * virture disk write sector
 * from start sector
 * */
xfat_err_t vdisk_write(struct _xdisk_t *disk, u8_t *buffer, u32_t start_sector, u32_t count)
{
    u32_t offset = start_sector * disk->sector_size;
    FILE * file = (FILE *)disk->data;

    int err = fseek(file, offset, SEEK_SET);
    if (err == -1)
    {
        printf("vdisk write seek_set error: 0x%x\n", offset);
        return FS_ERR_EIO;
    }

    err = (int)fwrite(buffer, disk->sector_size, count, file);
    if (err == -1)
    {
        printf("vdisk write failed : sector:%d, count:%d\n",(int)start_sector, (int)count);
        return FS_ERR_EIO;
    }

    fflush(file);
    return FS_ERR_EOK;    
}

/*
 * vdisk_close
 * virture disk close
 * 
 * */
xfat_err_t vdisk_close(struct _xdisk_t *disk)
{
    FILE *file = (FILE *)disk->data;
    fclose(file);
    return FS_ERR_EOK;
}

/*
 * vdisk_driver
 * virture disk driver
 * 
 * */
xdisk_driver_t vdisk_driver =
{
    .open  = vdisk_open,
    .close = vdisk_close,
    .read  = vdisk_read,
    .write = vdisk_write,
};